package com.example.movie.mate.service.impl;

import com.example.movie.mate.dao.mapper.*;
import com.example.movie.mate.exception.ServiceException;
import com.example.movie.mate.pojo.core.Principle;
import com.example.movie.mate.pojo.entity.Booking;
import com.example.movie.mate.pojo.entity.BookingSeat;
import com.example.movie.mate.pojo.entity.PlaySchedule;
import com.example.movie.mate.pojo.param.BookingAddNewParam;
import com.example.movie.mate.pojo.vo.*;
import com.example.movie.mate.service.IBookingService;
import com.example.movie.mate.web.StateCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class BookingServiceImpl implements IBookingService {

    @Autowired
    private BookingMapper bookingMapper;
    @Autowired
    private PlayScheduleMapper playScheduleMapper;
    @Autowired
    private HallMapper hallMapper;
    @Autowired
    private MovieMapper movieMapper;
    @Autowired
    private SeatMapper seatMapper;
    @Autowired
    private BookingSeatMapper bookingSeatMapper;

    @Override
    public void addNew(BookingAddNewParam param, Principle principle) {
        Long playScheduleId = param.getPlayScheduleId();
        PlayScheduleVO playSchedule = playScheduleMapper.selectById(playScheduleId);
        if (playSchedule == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "放映计划不存在");
        }

        LocalDateTime startTime = playSchedule.getStartTime();
        if (LocalDateTime.now().isAfter(startTime.minusMinutes(30))) {
            throw new ServiceException(StateCode.ERROR_FORBIDDEN, "仅放映前30分钟以上可以创建订单");
        }

        Long hallId = playSchedule.getHallId();
        HallVO hall = hallMapper.selectById(hallId);
        if (hall == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "影厅不存在");
        }

        Long movieId = playSchedule.getMovieId();
        MovieVO movie = movieMapper.selectById(movieId);
        if (movie == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "电影不存在");
        }

        Long[] seatIdList = param.getSeatIdList();
        if (seatIdList.length > playSchedule.getSeatStock()) {
            throw new ServiceException(StateCode.ERROR_CONFLICT, "该座次剩余座位数不够");
        }

        List<SeatVO> seatList = new ArrayList<>();
        for (Long seatId : seatIdList) {
            SeatVO seat = seatMapper.selectById(seatId);
            if (seat == null) {
                throw new ServiceException(StateCode.ERROR_NOT_FOUND, "座位不存在");
            }
            if (!seat.getHallId().equals(hallId)) {
                throw new ServiceException(StateCode.ERROR_CONFLICT, "座位参数错误");
            }

            int count = bookingSeatMapper.countByPlayScheduleIdAndSeatId(playScheduleId, seatId);
            if (count > 0) {
                throw new ServiceException(StateCode.ERROR_CONFLICT, "座位已被占用");
            }
            seatList.add(seat);
        }

        Booking booking = new Booking();
        booking.setUserId(principle.getId());
        booking.setPlayScheduleId(playScheduleId);
        booking.setMovieId(movieId);
        booking.setHallId(hallId);
        booking.setMovieName(movie.getName());
        booking.setHallName(hall.getName());
        booking.setStartTime(startTime);
        booking.setEndTime(playSchedule.getEndTime());
        booking.setTotalPrice(playSchedule.getPrice().multiply(new BigDecimal(seatList.size())));
        booking.setBookingTime(LocalDateTime.now());
        booking.setStatus(Booking.Status.UNPAID);
        bookingMapper.insert(booking);

        for (SeatVO seat : seatList) {
            BookingSeat bookingSeat = new BookingSeat();
            bookingSeat.setBookingId(booking.getId());
            bookingSeat.setPlayScheduleId(playScheduleId);
            bookingSeat.setSeatId(seat.getId());
            bookingSeat.setSeatRowNum(seat.getRowNum());
            bookingSeat.setSeatColNum(seat.getColNum());
            bookingSeatMapper.insert(bookingSeat);
        }

        PlaySchedule playScheduleForUpdate = new PlaySchedule();
        playScheduleForUpdate.setId(playScheduleId);
        playScheduleForUpdate.setSeatStock(playSchedule.getSeatStock() - seatList.size());
        playScheduleMapper.updateById(playScheduleForUpdate);
    }

    @Override
    public BookingFullInfoVO selectFullInfoByIdAndUser(Long id, Principle principle) {
        BookingSimpleInfoVO findResult = bookingMapper.selectByIdAndUserId(id, principle.getId());
        if (findResult == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "订单不存在");
        }

        List<BookingSeatVO> bookingSeatVOList = bookingSeatMapper.selectByBookingId(id);

        BookingFullInfoVO bookingFullInfoVO = new BookingFullInfoVO();
        BeanUtils.copyProperties(findResult, bookingFullInfoVO);
        bookingFullInfoVO.setBookingSeatList(bookingSeatVOList);
        return bookingFullInfoVO;
    }

    @Override
    public List<BookingSimpleInfoVO> selectSimpleInfoByUser(Principle principle) {
        List<BookingSimpleInfoVO> list = bookingMapper.selectByUserId(principle.getId());
        return list;
    }


}